using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

namespace ZSW.Framework.Signal
{
    public interface ISignalData
    {
    }

    public class SignalEvent : UnityEvent
    {
        public UnityAction SignalAction;
        public int Priority;  // 优先级

        public SignalEvent(UnityAction action, int priority = 0)
        {
            SignalAction = action;
            Priority = priority;
        }
    }

    public class SignalEvent<T> : UnityEvent<T>
    {
        public UnityAction<T> SignalAction;
        public int Priority;  // 优先级

        public SignalEvent(UnityAction<T> action, int priority = 0)
        {
            SignalAction = action;
            Priority = priority;
        }
    }

    public class SignalData : ISignalData
    {
        public List<SignalEvent> SignalEvents;
        public int MaxPriority { get; private set; }
        private int lastPriority;  // 上一次的优先级，减小排序次数

        public SignalData(UnityAction action, int priority = 0)
        {
            SignalEvents = new List<SignalEvent>();
            SignalEvents.Add(new SignalEvent(action, priority));
            MaxPriority = Mathf.Max(MaxPriority, priority);
            lastPriority = priority;
        }

        public void Add(UnityAction action, int priority = 0)
        {
            SignalEvents.Add(new SignalEvent(action, priority));
            MaxPriority = Mathf.Max(MaxPriority, priority);
            if (priority < lastPriority) sort();
            lastPriority = priority;
            sort();
        }

        public void Invoke()
        {
            for (int i = 0; i < SignalEvents.Count; i++)
            {
                SignalEvents[i].SignalAction?.Invoke();
            }
        }

        public void Remove(UnityAction action)
        {
            for (int i = 0; i < SignalEvents.Count; i++)
            {
                if (SignalEvents[i].SignalAction == action)
                {
                    SignalEvents.RemoveAt(i);
                    break;
                }
            }
        }

        private void sort()
        {
            SignalEvents.Sort((a, b) =>  b.Priority - a.Priority);
        }
    }

    public class SignalData<T> : ISignalData
    {
        public List<SignalEvent<T>> SignalEvents;
        public int MaxPriority { get; private set; }
        private int lastPriority;  // 上一次的优先级，减小排序次数

        public SignalData(UnityAction<T> action, int priority = 0)
        {
            SignalEvents = new List<SignalEvent<T>>();
            SignalEvents.Add(new SignalEvent<T>(action, priority));
            MaxPriority = Mathf.Max(MaxPriority, priority);
            lastPriority = priority;
        }

        public void Add(UnityAction<T> action, int priority = 0)
        {
            SignalEvents.Add(new SignalEvent<T>(action, priority));
            MaxPriority = Mathf.Max(MaxPriority, priority);
            if (priority < lastPriority) sort();
            lastPriority = priority;
        }

        public void Invoke(T arg)
        {
            for (int i = 0; i < SignalEvents.Count; i++)
            {
                SignalEvents[i].SignalAction?.Invoke(arg);
            }
        }

        public void Remove(UnityAction<T> action)
        {
            for (int i = 0; i < SignalEvents.Count; i++)
            {
                if (SignalEvents[i].SignalAction == action)
                {
                    SignalEvents.RemoveAt(i);
                    break;
                }
            }
        }

        private void sort()
        {
            SignalEvents.Sort((a, b) => b.Priority - a.Priority);
        }
    }
}